﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using LunarSF.SHomeWorkshop.LunarMarkdownEditor;

namespace LunarSF.SHomeWorkshop.LunarMarkdownEditor
{
    /// <summary>
    /// 表示时间轴上的节点。
    /// </summary>
    public class TimeAxisNode
    {
        public string Tag { get; set; }

        public TimeAxisDirection Direction { get; set; } = TimeAxisDirection.RightOrBottom;

        public string Comment { get; set; }
    }

    public enum TimeAxisDirection
    {
        LeftOrTop,
        RightOrBottom,
    }

    public class TimeAxisesList : List<TimeAxisNode>
    {
        public List<int> TopOrLeftCellIndexes
        {
            get
            {
                var list = new List<int>();
                for (int i = 0; i < this.Count; i++)
                {
                    var tnode = this[i];
                    if (string.IsNullOrWhiteSpace(tnode.Tag)) continue;

                    if (tnode.Direction == TimeAxisDirection.LeftOrTop)
                    {
                        list.Add(i + 1);
                    }
                }
                return list;
            }
        }

        public List<int> BottomOrRightCellIndexes
        {
            get
            {
                var list = new List<int>();
                for (int i = 0; i < this.Count; i++)
                {
                    var tnode = this[i];
                    if (string.IsNullOrWhiteSpace(tnode.Tag)) continue;

                    if (tnode.Direction == TimeAxisDirection.RightOrBottom)
                    {
                        list.Add(i + 1);
                    }
                }
                return list;
            }
        }

        public List<int> AllCellIndexes
        {
            get
            {
                var list = new List<int>();
                for (int i = 0; i < this.Count; i++)
                {
                    var tnode = this[i];
                    if (string.IsNullOrWhiteSpace(tnode.Tag)) continue;

                    list.Add(i + 1);
                }
                return list;
            }
        }
    }

    public static class TimeAxis
    {

        public enum TimeAxisLayout
        {
            /// <summary>
            /// 交叉布局，同一时间节点位置不能两侧都有内容。不支持空节点。
            /// </summary>
            CrossLayout,
            /// <summary>
            /// 对称布局，同一时间节点位置两侧都可以有内容。支持空节点。
            /// </summary>
            SymmetryLayout,
        }

        /// <summary>
        /// 编译时间轴。
        /// </summary>
        /// <param name="htmlBody"></param>
        /// <returns></returns>
        public static string CompileTimeAxises(ref MarkdownSharp.Markdown md, string htmlBody, bool forEpub)
        {
            if (string.IsNullOrEmpty(htmlBody)) return "";

            var lines = htmlBody.Split(new string[] { "\r\n", }, StringSplitOptions.None);

            var regTimeAxisStarter = new Regex(@"^\[[ 　\t]{0,}?[\+\-]?[ 　\t]{0,}?(时间轴|[横纵]轴|[hv][\- 　\t]*?轴|[hv][\- 　\t]*?Ax(is)?|[横纵]时间轴|[横纵]向(时间)?轴|[HV][ 　\t\-]{0,}?(Time[ 　\t]{0,})?Ax(is)?)", RegexOptions.IgnoreCase);
            var regTimeAxisEnder = new Regex(@"^\]");

            var result = new StringBuilder();

            StringBuilder sbTimeAxis = null;
            TimeAxisLayout layout = TimeAxisLayout.CrossLayout;           // 默认交叉布局
            var isVerticalAxis = false;
            string title = "";
            foreach (var line in lines)
            {
                var matchAxisStarter = regTimeAxisStarter.Match(line);
                if (matchAxisStarter.Success)
                {
                    title = line.Substring(matchAxisStarter.Length).Trim(new char[] { ' ', '　', '\t', ':', '：', });

                    sbTimeAxis = new StringBuilder();
                    var text = matchAxisStarter.Value.Trim(new char[] { ' ', '　', '\t', '[', '【', }).ToLower();
                    if (text.Length > 0)
                    {
                        var fstChar = text[0];
                        if (fstChar == '+')
                        {
                            layout = TimeAxisLayout.SymmetryLayout;
                        }
                        text = text.Trim(new char[] { ' ', '　', '\t', '+', '-', });
                        if (text.Length > 0)
                        {
                            fstChar = text[0];
                            if (fstChar == 'v' || fstChar == '纵')  // 默认横轴
                            {
                                isVerticalAxis = true;
                            }
                            else
                            {
                                isVerticalAxis = false;
                            }
                        }
                    }
                }
                else if (regTimeAxisEnder.Match(line).Success)
                {
                    if (sbTimeAxis == null)
                    {
                        result.Append(line + "\r\n");
                        continue;  // 非时间轴的方块区域尾，直接忽略会导致原始方块区域出错。
                    }

                    result.Append(CompileTimeAxis(ref md, sbTimeAxis.ToString(), title, layout, isVerticalAxis, forEpub));
                    sbTimeAxis = null;
                }
                else
                {
                    if (sbTimeAxis != null)
                    {
                        sbTimeAxis.Append(line + "\r\n");
                        continue;
                    }

                    result.Append(line + "\r\n");
                }
            }
            return result.ToString();
        }

        /// <summary>
        /// 编译一个
        /// </summary>
        /// <param name="src">一个方块区域，标头文本应该是“时间轴”</param>
        /// <returns></returns>
        private static string CompileTimeAxis(ref MarkdownSharp.Markdown md, string src, string title, TimeAxisLayout layout, bool isVirticalAxis = false, bool forEpub = false)
        {
            if (string.IsNullOrWhiteSpace(src)) return "";

            var lines = src.Split(new string[] { "\r\n", }, StringSplitOptions.None);
            if (forEpub)
            {
                var sb = new StringBuilder();

                bool doubleDirection = false;  // 是否双向
                string preMark = null;
                for (int lineIndex = 0; lineIndex < lines.Length; lineIndex++)
                {
                    if (string.IsNullOrWhiteSpace(lines[lineIndex])) continue;
                    if (lines[lineIndex].IndexOf("=>") >= 0)
                    {
                        if (preMark == null)
                        {
                            preMark = "=>";
                            continue;
                        }
                        else
                        {
                            if (preMark == "=>") continue;
                            else
                            {
                                doubleDirection = true;
                                break;
                            }
                        }
                    }
                    else if (lines[lineIndex].IndexOf("<=") >= 0)
                    {
                        if (preMark == null)
                        {
                            preMark = "<=";
                            continue;
                        }
                        else
                        {
                            if (preMark == "<=") continue;
                            else
                            {
                                doubleDirection = true;
                                break;
                            }
                        }
                    }
                }

                if (doubleDirection)
                {
                    if (string.IsNullOrWhiteSpace(title) == false)
                    {
                        sb.Append("|" + title + "|\r\n|-:|:-:|:-|\r\n");  // table's caption
                    }

                    for (int lineIndex = 0; lineIndex < lines.Length; lineIndex++)
                    {
                        if (string.IsNullOrWhiteSpace(lines[lineIndex])) continue;
                        var rightBreaker = lines[lineIndex].IndexOf("=>");
                        var leftBreaker = lines[lineIndex].IndexOf("<=");
                        if (rightBreaker >= 0)
                        {
                            sb.Append("||" + lines[lineIndex].Replace("=>", "|").Replace("<=", "|") + "\r\n");
                        }
                        else if (leftBreaker >= 0)
                        {
                            sb.Append("|" + lines[lineIndex].Substring(leftBreaker + 2) + "|" + lines[lineIndex].Substring(0, leftBreaker) + "\r\n");
                        }
                        else
                        {
                            sb.Append("|" + lines[lineIndex] + "\r\n");
                        }
                    }
                }
                else
                {
                    sb.Append("|" + title + "|\r\n|-:|:-|\r\n");  // table's caption
                    
                    for (int lineIndex = 0; lineIndex < lines.Length; lineIndex++)
                    {
                        if (string.IsNullOrWhiteSpace(lines[lineIndex])) continue;

                        sb.Append("|" + lines[lineIndex].Replace("=>", "|").Replace("<=", "|") + "\r\n");
                    }
                }
                return sb.ToString();
            }

            var topOrLeftNodesCount = 0;
            var bottomOrRightNodesCount = 0;
            var list = new TimeAxisesList();
            for (int lineIndex = 0; lineIndex < lines.Length; lineIndex++)
            {
                var line = lines[lineIndex];

                int index;
                var index1 = line.IndexOf("<=");
                if (index1 >= 0)
                {
                    var index2 = line.IndexOf("=>");
                    if (index2 >= 0)
                    {
                        index = Math.Min(index1, index2);
                    }
                    else
                    {
                        index = index1;
                    }
                }
                else
                {
                    var index2 = line.IndexOf("=>");
                    if (index2 >= 0)
                    {
                        index = index2;
                    }
                    else index = -1;
                }

                if (index < 0) continue;

                if (string.IsNullOrWhiteSpace(line.Substring(0, index)))
                {
                    line = "`--Empty--` " + line;
                    index += "`--Empty--` ".Length;
                    //continue;  // 注意：不再忽略没有 Tag 的行！！！空标签直接显示空框好了。
                }

                var direction = line.Substring(index, 2) == "=>" ? TimeAxisDirection.RightOrBottom : TimeAxisDirection.LeftOrTop;
                list.Add(new TimeAxisNode()
                {
                    Tag = line.Substring(0, index).Trim(),
                    Comment = line.Substring(index + 2).Trim(),
                    Direction = direction,
                });

                if (string.IsNullOrWhiteSpace(list[list.Count - 1].Tag) == false)
                {
                    switch (direction)
                    {
                        case TimeAxisDirection.LeftOrTop:
                            {
                                topOrLeftNodesCount++;
                                break;
                            }
                        default:
                            {
                                bottomOrRightNodesCount++;
                                break;
                            }
                    }
                }
            }

            if (list.Count <= 0) return src;

            var htmlStringBuilder = new StringBuilder();
            htmlStringBuilder.Append("<table");

            if (isVirticalAxis == false)
            {
                htmlStringBuilder.Append(" class='h_time_axis'>");

                // 横向轴
                if (bottomOrRightNodesCount > 0 && topOrLeftNodesCount <= 0)
                {
                    var cols = list.Count * 3 - 1;
                    var bList = list.BottomOrRightCellIndexes;

                    // 只有轴下侧有节点 
                    // 共 5 行

                    // 第 1 行是轴
                    if (string.IsNullOrWhiteSpace(title))
                    {
                        htmlStringBuilder.Append($"<tr><td class='h_time_axis_title' colspan='{cols}'><li class='h_time_axis_title'> &gt;&gt;&gt; 时间轴 &gt;&gt;&gt; </li></td></tr>");
                    }
                    else
                    {
                        htmlStringBuilder.Append($"<tr><td class='h_time_axis_title' colspan='{cols}'><li class='h_time_axis_title'>{CustomMarkdownSupport.FormatLineContent(ref md, title)}</li></td></tr>");
                    }

                    // 第 2 行是连接线
                    htmlStringBuilder.Append($"<tr>");
                    for (int i = 1; i <= cols; i++)
                    {
                        var tagText = list[(i - 1) / 3].Tag;

                        if (tagText != "`--Empty--`" && (i - 1) % 3 == 0 && bList.Contains((i - 1) / 3 + 1))
                        {
                            htmlStringBuilder.Append("<td class='h_time_axis_line'><li class='simple'></li></td>");
                        }
                        else htmlStringBuilder.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                    }
                    htmlStringBuilder.Append("</tr>");

                    // 第 3 行是 Tag 单元格
                    for (int i = 1; i <= cols; i++)
                    {
                        if ((i - 1) % 3 == 0 && bList.Contains((i - 1) / 3 + 1))
                        {
                            var tagText = list[(i - 1) / 3].Tag;
                            if (tagText == "`--Empty--`")
                            {
                                htmlStringBuilder.Append($"<td colspan='2' class='h_time_axis_empty'><li class='simple' style='color:transparent;'>■</li></td>");
                            }
                            else
                            {
                                htmlStringBuilder.Append($"<td colspan='2' class='h_time_axis_tag'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, tagText)}</li></td>");
                            }
                        }
                        else if (i % 3 == 0)  // 中间一格被合并掉了
                        {
                            htmlStringBuilder.Append($"<td class='h_time_axis_empty'><li class='simple'></li></td>");
                        }
                    }
                    htmlStringBuilder.Append("</tr>");

                    // 第 4 行是和第 2 行一样的连接线
                    var row4 = new StringBuilder();
                    row4.Append($"<tr>");
                    for (int i = 1; i <= cols; i++)
                    {
                        if ((i - 1) % 3 == 0 && bList.Contains((i - 1) / 3 + 1))
                        {
                            var tagText = list[(i - 1) / 3].Tag;

                            if (tagText != "`--Empty--`" && string.IsNullOrWhiteSpace(list[(i - 1) / 3].Comment) == false)
                            {
                                // 没有 Tag，但有 Comment，显示 Comment，但不显示连接线
                                row4.Append("<td class='h_time_axis_line'><li class='simple'></li></td>");
                            }
                            else
                            {
                                row4.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                            }
                        }
                        else row4.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                    }
                    row4.Append("</tr>");

                    // 第 5 行是和第 3 行一样的单元格，但是内容不同。
                    var row5 = new StringBuilder();
                    bool hasComment = false;
                    for (int i = 1; i <= cols; i++)
                    {
                        if ((i - 1) % 3 == 0 && bList.Contains((i - 1) / 3 + 1))
                        {
                            if (string.IsNullOrWhiteSpace(list[(i - 1) / 3].Comment) == false)
                            {
                                row5.Append($"<td colspan='2' class='h_time_axis_comment'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, list[(i - 1) / 3].Comment)}</li></td>");
                                if (hasComment == false) hasComment = true;
                            }
                            else
                            {
                                row5.Append($"<td colspan='2' class='h_time_axis_empty'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, list[(i - 1) / 3].Comment)}</li></td>");
                            }
                        }
                        else if (i % 3 == 0)  // 中间一格被合并掉了
                        {
                            row5.Append($"<td class='h_time_axis_empty'><li class='simple'></li></td>");
                        }
                    }
                    row5.Append("</tr>");

                    if (hasComment)
                    {
                        htmlStringBuilder.Append(row4);
                        htmlStringBuilder.Append(row5);
                    }
                }
                else if (topOrLeftNodesCount > 0 && bottomOrRightNodesCount <= 0)
                {
                    var cols = list.Count * 3 - 1;
                    var tList = list.TopOrLeftCellIndexes;

                    // 只有轴上侧有节点
                    // 共 5 行

                    // 第 1 行是和第 3 行一样的单元格，但是内容不同。
                    var row1 = new StringBuilder();
                    var hasComment = false;
                    for (int i = 1; i <= cols; i++)
                    {
                        if ((i - 1) % 3 == 0 && tList.Contains((i - 1) / 3 + 1))
                        {
                            if (string.IsNullOrWhiteSpace(list[(i - 1) / 3].Comment) == false)
                            {
                                // 没有 Tag，但有 Comment，显示 Comment，但不显示连接线
                                row1.Append($"<td colspan='2' class='h_time_axis_comment'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, list[(i - 1) / 3].Comment)}</li></td>");
                                if (hasComment == false) hasComment = true;
                            }
                            else
                            {
                                row1.Append($"<td colspan='2' class='h_time_axis_empty'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, list[(i - 1) / 3].Comment)}</li></td>");
                            }
                        }
                        else if (i % 3 == 0)  // 中间一格被合并掉了
                        {
                            row1.Append($"<td class='h_time_axis_empty'><li class='simple'></li></td>");
                        }
                    }
                    row1.Append("</tr>");

                    // 第 2 行是连接线
                    var row2 = new StringBuilder();
                    row2.Append($"<tr>");
                    for (int i = 1; i <= cols; i++)
                    {
                        if ((i - 1) % 3 == 0 && tList.Contains((i - 1) / 3 + 1))
                        {
                            var tagText = list[(i - 1) / 3].Tag;
                            if (tagText != "`--Empty--`" && string.IsNullOrWhiteSpace(list[(i - 1) / 3].Comment) == false)
                            {

                                row2.Append("<td class='h_time_axis_line'><li class='simple'></li></td>");
                            }
                            else
                            {
                                row2.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                            }
                        }
                        else row2.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                    }
                    row2.Append("</tr>");

                    if (hasComment)
                    {
                        htmlStringBuilder.Append(row1);
                        htmlStringBuilder.Append(row2);
                    }

                    // 第 3 行是 Tag 单元格
                    for (int i = 1; i <= cols; i++)
                    {
                        if ((i - 1) % 3 == 0 && tList.Contains((i - 1) / 3 + 1))
                        {
                            var tagText = list[(i - 1) / 3].Tag;
                            if (tagText == "`--Empty--`")
                            {
                                htmlStringBuilder.Append($"<td colspan='2' class='h_time_axis_empty'><li class='simple' style='color:transparent;'>■</li></td>");
                            }
                            else
                            {
                                htmlStringBuilder.Append($"<td colspan='2' class='h_time_axis_tag'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, list[(i - 1) / 3].Tag)}</li></td>");
                            }
                        }
                        else if (i % 3 == 0)  // 中间一格被合并掉了
                        {
                            htmlStringBuilder.Append($"<td class='h_time_axis_empty'><li class='simple'></li></td>");
                        }
                    }
                    htmlStringBuilder.Append("</tr>");

                    // 第 4 行是和第 2 行一样的连接线
                    htmlStringBuilder.Append($"<tr>");
                    for (int i = 1; i <= cols; i++)
                    {
                        var tagText = list[(i - 1) / 3].Tag;
                        if (tagText != "`--Empty--`" && (i - 1) % 3 == 0 && tList.Contains((i - 1) / 3 + 1))
                        {
                            htmlStringBuilder.Append("<td class='h_time_axis_line'><li class='simple'></li></td>");
                        }
                        else htmlStringBuilder.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                    }
                    htmlStringBuilder.Append("</tr>");

                    // 第 5 行是轴
                    if (string.IsNullOrWhiteSpace(title))
                    {
                        htmlStringBuilder.Append($"<tr><td class='h_time_axis_title' colspan='{cols}'><li class='h_time_axis_title'> &gt;&gt;&gt; 时间轴 &gt;&gt;&gt; </li></td></tr>");
                    }
                    else
                    {
                        htmlStringBuilder.Append($"<tr><td class='h_time_axis_title' colspan='{cols}'><li class='h_time_axis_title'>{CustomMarkdownSupport.FormatLineContent(ref md, title)}</li></td></tr>");
                    }
                }
                else if (topOrLeftNodesCount > 0 && bottomOrRightNodesCount > 0)
                {
                    switch (layout)
                    {
                        case TimeAxisLayout.CrossLayout:
                            {
                                // 轴上下两侧都有节点
                                var cols = list.Count * 3 - 1;
                                var iList = list.AllCellIndexes;

                                // 轴上下侧有节点 
                                // 共 9 行

                                // 第 1 行是和第 3 行一样的单元格，但是内容不同。
                                bool ignoreNextCell = false;
                                var row1 = new StringBuilder();
                                var hasComment = false;
                                for (int i = 1; i <= cols; i++)
                                {
                                    if ((i - 1) % 3 == 0 && iList.Contains((i - 1) / 3 + 1) && list[(i - 1) / 3].Direction == TimeAxisDirection.LeftOrTop)
                                    {
                                        if (string.IsNullOrWhiteSpace(list[(i - 1) / 3].Comment) == false)
                                        {
                                            row1.Append($"<td colspan='2' class='h_time_axis_comment'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, list[(i - 1) / 3].Comment)}</li></td>");
                                            if (hasComment == false) hasComment = true;
                                        }
                                        else
                                        {
                                            row1.Append($"<td colspan='2' class='h_time_axis_empty'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, list[(i - 1) / 3].Comment)}</li></td>");
                                        }
                                        ignoreNextCell = true;
                                    }
                                    else
                                    {
                                        if (ignoreNextCell)  // 中间一格被合并掉了
                                        {
                                            ignoreNextCell = false;
                                        }
                                        else
                                        {
                                            row1.Append($"<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                        }
                                    }
                                }
                                row1.Append("</tr>");

                                // 第 2 行是连接线
                                var row2 = new StringBuilder();
                                row2.Append($"<tr>");
                                for (int i = 1; i <= cols; i++)
                                {
                                    if ((i - 1) % 3 == 0 && iList.Contains((i - 1) / 3 + 1) && list[(i - 1) / 3].Direction == TimeAxisDirection.LeftOrTop)
                                    {
                                        var tagText = list[(i - 1) / 3].Tag;

                                        if (tagText != "`--Empty--`" && string.IsNullOrWhiteSpace(list[(i - 1) / 3].Comment) == false)
                                        {
                                            row2.Append("<td class='h_time_axis_line'><li class='simple'></li></td>");
                                        }
                                        else
                                        {
                                            row2.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                        }
                                    }
                                    else row2.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                }
                                row2.Append("</tr>");

                                if (hasComment)
                                {
                                    htmlStringBuilder.Append(row1);
                                    htmlStringBuilder.Append(row2);
                                }

                                // 第 3 行是 Tag 单元格
                                ignoreNextCell = false;
                                for (int i = 1; i <= cols; i++)
                                {
                                    if ((i - 1) % 3 == 0 && iList.Contains((i - 1) / 3 + 1) && list[(i - 1) / 3].Direction == TimeAxisDirection.LeftOrTop)
                                    {
                                        var tagText = list[(i - 1) / 3].Tag;
                                        if (tagText == "`--Empty--`")
                                        {
                                            htmlStringBuilder.Append($"<td colspan='2' class='h_time_axis_empty'><li class='simple' style='color:transparent;'>■</li></td>");
                                        }
                                        else
                                        {
                                            htmlStringBuilder.Append($"<td colspan='2' class='h_time_axis_tag'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, list[(i - 1) / 3].Tag)}</li></td>");
                                        }
                                        ignoreNextCell = true;
                                    }
                                    else
                                    {
                                        if (ignoreNextCell)  // 中间一格被合并掉了
                                        {
                                            ignoreNextCell = false;
                                        }
                                        else
                                        {
                                            htmlStringBuilder.Append($"<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                        }
                                    }
                                }
                                htmlStringBuilder.Append("</tr>");

                                // 第 4 行是和第 2 行一样的连接线
                                htmlStringBuilder.Append($"<tr>");
                                for (int i = 1; i <= cols; i++)
                                {
                                    var tagText = list[(i - 1) / 3].Tag;
                                    if (tagText != "`--Empty--`" && (i - 1) % 3 == 0 && iList.Contains((i - 1) / 3 + 1) && list[(i - 1) / 3].Direction == TimeAxisDirection.LeftOrTop)
                                    {
                                        htmlStringBuilder.Append("<td class='h_time_axis_line'><li class='simple'></li></td>");
                                    }
                                    else htmlStringBuilder.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                }
                                htmlStringBuilder.Append("</tr>");

                                // 第 5 行是轴
                                if (string.IsNullOrWhiteSpace(title))
                                {
                                    htmlStringBuilder.Append($"<tr><td class='h_time_axis_title' colspan='{cols}'><li class='h_time_axis_title'> &gt;&gt;&gt; 时间轴 &gt;&gt;&gt; </li></td></tr>");
                                }
                                else
                                {
                                    htmlStringBuilder.Append($"<tr><td class='h_time_axis_title' colspan='{cols}'><li class='h_time_axis_title'>{CustomMarkdownSupport.FormatLineContent(ref md, title)}</li></td></tr>");
                                }

                                // 第 6 行是连接线
                                htmlStringBuilder.Append($"<tr>");
                                for (int i = 1; i <= cols; i++)
                                {
                                    var tagText = list[(i - 1) / 3].Tag;

                                    if (tagText != "`--Empty--`" && (i - 1) % 3 == 0 && iList.Contains((i - 1) / 3 + 1) && list[(i - 1) / 3].Direction == TimeAxisDirection.RightOrBottom)
                                    {
                                        htmlStringBuilder.Append("<td class='h_time_axis_line'><li class='simple'></li></td>");
                                    }
                                    else htmlStringBuilder.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                }
                                htmlStringBuilder.Append("</tr>");

                                // 第 7 行是 Tag 单元格
                                ignoreNextCell = false;
                                for (int i = 1; i <= cols; i++)
                                {
                                    if ((i - 1) % 3 == 0 && iList.Contains((i - 1) / 3 + 1) && list[(i - 1) / 3].Direction == TimeAxisDirection.RightOrBottom)
                                    {
                                        var tagText = list[(i - 1) / 3].Tag;
                                        if (tagText == "`--Empty--`")
                                        {
                                            htmlStringBuilder.Append($"<td colspan='2' class='h_time_axis_empty'><li class='simple' style='transparent'>■</li></td>");
                                        }
                                        else
                                        {
                                            htmlStringBuilder.Append($"<td colspan='2' class='h_time_axis_tag'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, list[(i - 1) / 3].Tag)}</li></td>");
                                        }
                                        ignoreNextCell = true;
                                    }
                                    else
                                    {
                                        if (ignoreNextCell)  // 中间一格被合并掉了
                                        {
                                            ignoreNextCell = false;
                                        }
                                        else
                                        {
                                            htmlStringBuilder.Append($"<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                        }
                                    }
                                }
                                htmlStringBuilder.Append("</tr>");

                                // 第 8 行是和第 2 行一样的连接线
                                var row8 = new StringBuilder();
                                row8.Append($"<tr>");
                                for (int i = 1; i <= cols; i++)
                                {
                                    if ((i - 1) % 3 == 0 && iList.Contains((i - 1) / 3 + 1) && list[(i - 1) / 3].Direction == TimeAxisDirection.RightOrBottom)
                                    {
                                        var tagText = list[(i - 1) / 3].Tag;

                                        if (tagText != "`--Empty--`" && string.IsNullOrWhiteSpace(list[(i - 1) / 3].Comment) == false)
                                        {
                                            row8.Append("<td class='h_time_axis_line'><li class='simple'></li></td>");
                                        }
                                        else
                                        {
                                            row8.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                        }
                                    }
                                    else row8.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                }
                                row8.Append("</tr>");

                                // 第 9 行是和第 3 行一样的单元格，但是内容不同。
                                var row9 = new StringBuilder();
                                var hasComment2 = false;
                                ignoreNextCell = false;
                                for (int i = 1; i <= cols; i++)
                                {
                                    if ((i - 1) % 3 == 0 && iList.Contains((i - 1) / 3 + 1) && list[(i - 1) / 3].Direction == TimeAxisDirection.RightOrBottom)
                                    {
                                        if (string.IsNullOrWhiteSpace(list[(i - 1) / 3].Comment) == false)
                                        {
                                            row9.Append($"<td colspan='2' class='h_time_axis_comment'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, list[(i - 1) / 3].Comment)}</li></td>");
                                            if (hasComment2 == false) hasComment2 = true;
                                        }
                                        else
                                        {
                                            row9.Append($"<td colspan='2' class='h_time_axis_empty'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, list[(i - 1) / 3].Comment)}</li></td>");
                                        }
                                        ignoreNextCell = true;
                                    }
                                    else
                                    {
                                        if (ignoreNextCell)   // 中间一格被合并掉了
                                        {
                                            ignoreNextCell = false;
                                        }
                                        else
                                        {
                                            row9.Append($"<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                        }
                                    }
                                }
                                row9.Append("</tr>");

                                if (hasComment2)
                                {
                                    htmlStringBuilder.Append(row8);
                                    htmlStringBuilder.Append(row9);
                                }
                                break;
                            }
                        case TimeAxisLayout.SymmetryLayout:
                            {
                                // 横轴，上下都有，对称布局
                                var ltList = new TimeAxisesList();
                                var rbList = new TimeAxisesList();
                                foreach (var li in list)
                                {
                                    switch (li.Direction)
                                    {
                                        case TimeAxisDirection.LeftOrTop:
                                            {
                                                ltList.Add(li); break;
                                            }
                                        case TimeAxisDirection.RightOrBottom:
                                            {
                                                rbList.Add(li); break;
                                            }
                                    }
                                }

                                var maxCount = Math.Max(ltList.Count, rbList.Count);
                                var cols = maxCount * 3 - 1;

                                var iLtList = ltList.AllCellIndexes;
                                var iRbList = rbList.AllCellIndexes;

                                // 轴上下侧有节点 
                                // 共 9 行

                                // 第 1 行是和第 3 行一样的单元格，但是内容不同。
                                bool ignoreNextCell = false;
                                var row1 = new StringBuilder();
                                var hasComment = false;
                                for (int i = 1; i <= cols; i++)
                                {
                                    if ((i - 1) % 3 == 0 && iLtList.Contains((i - 1) / 3 + 1) && ltList[(i - 1) / 3].Direction == TimeAxisDirection.LeftOrTop)
                                    {
                                        if (string.IsNullOrWhiteSpace(ltList[(i - 1) / 3].Comment) == false)
                                        {
                                            row1.Append($"<td colspan='2' class='h_time_axis_comment'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, ltList[(i - 1) / 3].Comment)}</li></td>");
                                            if (hasComment == false) hasComment = true;
                                        }
                                        else
                                        {
                                            row1.Append($"<td colspan='2' class='h_time_axis_empty'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, ltList[(i - 1) / 3].Comment)}</li></td>");
                                        }
                                        ignoreNextCell = true;
                                    }
                                    else
                                    {
                                        if (ignoreNextCell)  // 中间一格被合并掉了
                                        {
                                            ignoreNextCell = false;
                                        }
                                        else
                                        {
                                            row1.Append($"<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                        }
                                    }
                                }
                                row1.Append("</tr>");

                                // 第 2 行是连接线
                                var row2 = new StringBuilder();
                                row2.Append($"<tr>");
                                for (int i = 1; i <= cols; i++)
                                {
                                    if ((i - 1) % 3 == 0 && iLtList.Contains((i - 1) / 3 + 1) && ltList[(i - 1) / 3].Direction == TimeAxisDirection.LeftOrTop)
                                    {
                                        var tagText = ltList[(i - 1) / 3].Tag;

                                        if (tagText != "`--Empty--`" && string.IsNullOrWhiteSpace(ltList[(i - 1) / 3].Comment) == false)
                                        {
                                            row2.Append("<td class='h_time_axis_line'><li class='simple'></li></td>");
                                        }
                                        else
                                        {
                                            row2.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                        }
                                    }
                                    else row2.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                }
                                row2.Append("</tr>");

                                if (hasComment)
                                {
                                    htmlStringBuilder.Append(row1);
                                    htmlStringBuilder.Append(row2);
                                }

                                // 第 3 行是 Tag 单元格
                                ignoreNextCell = false;
                                for (int i = 1; i <= cols; i++)
                                {
                                    if ((i - 1) % 3 == 0 && iLtList.Contains((i - 1) / 3 + 1) && ltList[(i - 1) / 3].Direction == TimeAxisDirection.LeftOrTop)
                                    {
                                        var tagText = ltList[(i - 1) / 3].Tag;
                                        if (tagText == "`--Empty--`")
                                        {
                                            htmlStringBuilder.Append($"<td colspan='2' class='h_time_axis_empty'><li class='simple' style='color:transparent;'>■</li></td>");
                                        }
                                        else
                                        {
                                            htmlStringBuilder.Append($"<td colspan='2' class='h_time_axis_tag'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, ltList[(i - 1) / 3].Tag)}</li></td>");
                                        }
                                        ignoreNextCell = true;
                                    }
                                    else
                                    {
                                        if (ignoreNextCell)  // 中间一格被合并掉了
                                        {
                                            ignoreNextCell = false;
                                        }
                                        else
                                        {
                                            htmlStringBuilder.Append($"<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                        }
                                    }
                                }
                                htmlStringBuilder.Append("</tr>");

                                // 第 4 行是和第 2 行一样的连接线
                                htmlStringBuilder.Append($"<tr>");
                                for (int i = 1; i <= cols; i++)
                                {
                                    if ((i - 1) % 3 == 0 && iLtList.Contains((i - 1) / 3 + 1) && ltList[(i - 1) / 3].Direction == TimeAxisDirection.LeftOrTop)
                                    {
                                        var tagText = ltList[(i - 1) / 3].Tag;
                                        if (tagText == "`--Empty--`")
                                        {
                                            htmlStringBuilder.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                        }
                                        else
                                        {
                                            htmlStringBuilder.Append("<td class='h_time_axis_line'><li class='simple'></li></td>");
                                        }
                                    }
                                    else htmlStringBuilder.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                }
                                htmlStringBuilder.Append("</tr>");

                                // 第 5 行是轴
                                if (string.IsNullOrWhiteSpace(title))
                                {
                                    htmlStringBuilder.Append($"<tr><td class='h_time_axis_title' colspan='{cols}'><li class='h_time_axis_title'> &gt;&gt;&gt; 时间轴 &gt;&gt;&gt; </li></td></tr>");
                                }
                                else
                                {
                                    htmlStringBuilder.Append($"<tr><td class='h_time_axis_title' colspan='{cols}'><li class='h_time_axis_title'>{CustomMarkdownSupport.FormatLineContent(ref md, title)}</li></td></tr>");
                                }

                                // 第 6 行是连接线
                                htmlStringBuilder.Append($"<tr>");
                                for (int i = 1; i <= cols; i++)
                                {
                                    if ((i - 1) % 3 == 0 && iRbList.Contains((i - 1) / 3 + 1) && rbList[(i - 1) / 3].Direction == TimeAxisDirection.RightOrBottom)
                                    {
                                        var tagText = rbList[(i - 1) / 3].Tag;
                                        if (tagText == "`--Empty--`")
                                        {
                                            htmlStringBuilder.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                        }
                                        else
                                        {
                                            htmlStringBuilder.Append("<td class='h_time_axis_line'><li class='simple'></li></td>");
                                        }
                                    }
                                    else htmlStringBuilder.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                }
                                htmlStringBuilder.Append("</tr>");

                                // 第 7 行是 Tag 单元格
                                ignoreNextCell = false;
                                for (int i = 1; i <= cols; i++)
                                {
                                    if ((i - 1) % 3 == 0 && iRbList.Contains((i - 1) / 3 + 1) && rbList[(i - 1) / 3].Direction == TimeAxisDirection.RightOrBottom)
                                    {
                                        var tagText = rbList[(i - 1) / 3].Tag;
                                        if (tagText == "`--Empty--`")
                                        {
                                            htmlStringBuilder.Append($"<td colspan='2' class='h_time_axis_empty'><li class='simple' style='color:transparent;'>■</li></td>");
                                        }
                                        else
                                        {
                                            htmlStringBuilder.Append($"<td colspan='2' class='h_time_axis_tag'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, rbList[(i - 1) / 3].Tag)}</li></td>");
                                        }
                                        ignoreNextCell = true;
                                    }
                                    else
                                    {
                                        if (ignoreNextCell)  // 中间一格被合并掉了
                                        {
                                            ignoreNextCell = false;
                                        }
                                        else
                                        {
                                            htmlStringBuilder.Append($"<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                        }
                                    }
                                }
                                htmlStringBuilder.Append("</tr>");

                                // 第 8 行是和第 2 行一样的连接线
                                var row8 = new StringBuilder();
                                row8.Append($"<tr>");
                                for (int i = 1; i <= cols; i++)
                                {
                                    if ((i - 1) % 3 == 0 && iRbList.Contains((i - 1) / 3 + 1) && rbList[(i - 1) / 3].Direction == TimeAxisDirection.RightOrBottom)
                                    {
                                        var tagText = rbList[(i - 1) / 3].Tag;

                                        if (tagText != "`--Empty--`" && string.IsNullOrWhiteSpace(rbList[(i - 1) / 3].Comment) == false)
                                        {
                                            row8.Append("<td class='h_time_axis_line'><li class='simple'></li></td>");
                                        }
                                        else
                                        {
                                            row8.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                        }
                                    }
                                    else row8.Append("<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                }
                                row8.Append("</tr>");

                                // 第 9 行是和第 3 行一样的单元格，但是内容不同。
                                var row9 = new StringBuilder();
                                var hasComment2 = false;
                                ignoreNextCell = false;
                                for (int i = 1; i <= cols; i++)
                                {
                                    if ((i - 1) % 3 == 0 && iRbList.Contains((i - 1) / 3 + 1) && rbList[(i - 1) / 3].Direction == TimeAxisDirection.RightOrBottom)
                                    {
                                        if (string.IsNullOrWhiteSpace(rbList[(i - 1) / 3].Comment) == false)
                                        {
                                            row9.Append($"<td colspan='2' class='h_time_axis_comment'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, rbList[(i - 1) / 3].Comment)}</li></td>");
                                            if (hasComment2 == false) hasComment2 = true;
                                        }
                                        else
                                        {
                                            row9.Append($"<td colspan='2' class='h_time_axis_empty'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, rbList[(i - 1) / 3].Comment)}</li></td>");
                                        }
                                        ignoreNextCell = true;
                                    }
                                    else
                                    {
                                        if (ignoreNextCell)   // 中间一格被合并掉了
                                        {
                                            ignoreNextCell = false;
                                        }
                                        else
                                        {
                                            row9.Append($"<td class='h_time_axis_empty'><li class='simple'></li></td>");
                                        }
                                    }
                                }
                                row9.Append("</tr>");

                                if (hasComment2)
                                {
                                    htmlStringBuilder.Append(row8);
                                    htmlStringBuilder.Append(row9);
                                }

                                break;
                            }
                    }
                }
            }
            else
            {
                htmlStringBuilder.Append(" class='v_time_axis'>");

                // 纵轴
                switch (layout)
                {
                    case TimeAxisLayout.CrossLayout:
                        {
                            // 纵向轴
                            TimeAxisCell[,] array = new TimeAxisCell[list.Count * 3 - 1, 9];
                            for (int ai = 0; ai < array.Length / 9; ai++)
                            {
                                for (int ac = 0; ac < 9; ac++)
                                {
                                    if (ai >= 1 && ac == 4)
                                    {
                                        array[ai, ac] = new TimeAxisCell()
                                        {
                                            Type = TimeAxisCellType.Hided,   // 中轴
                                        };
                                    }
                                    else
                                    {
                                        array[ai, ac] = new TimeAxisCell()
                                        {
                                            Type = TimeAxisCellType.Empty,
                                        };
                                    }
                                }
                            }

                            for (int li = 0; li < list.Count; li++)
                            {
                                var rowIndex = (li * 3 + 1) - 1;

                                array[rowIndex, 4].Type = TimeAxisCellType.Title;             // 第 5 列总为标题

                                var node = list[li];
                                if (node.Direction == TimeAxisDirection.LeftOrTop)
                                {
                                    // 设置对应单元格的状态。
                                    if (string.IsNullOrWhiteSpace(node.Comment))
                                    {
                                        array[rowIndex, 0].Type = TimeAxisCellType.EmptyComment;  // 第 1 列是Comment
                                        array[rowIndex, 1].Type = TimeAxisCellType.Empty;         // 第 2 列应为底边框线
                                    }
                                    else
                                    {
                                        array[rowIndex, 0].Type = TimeAxisCellType.Comment;       // 第 1 列是Comment
                                        array[rowIndex, 0].Content = node.Comment;

                                        if (node.Tag == "`--Empty--`")
                                        {
                                            array[rowIndex, 1].Type = TimeAxisCellType.Empty;          // 第 2 列应无边框线
                                        }
                                        else
                                        {
                                            array[rowIndex, 1].Type = TimeAxisCellType.Line;          // 第 2 列应为底边框线
                                        }
                                    }
                                    array[rowIndex + 1, 0].Type = TimeAxisCellType.Hided;         // 第 1 列下一行单元格应被隐藏


                                    if (string.IsNullOrWhiteSpace(node.Tag))
                                    {
                                        array[rowIndex, 2].Type = TimeAxisCellType.Empty;         // 第 3 列应为Tag
                                        array[rowIndex, 3].Type = TimeAxisCellType.Empty;         // 第 4 列应无底边框线
                                    }
                                    else
                                    {
                                        if (node.Tag == "`--Empty--`")
                                        {
                                            array[rowIndex, 2].Type = TimeAxisCellType.Empty;           // 第 3 列应为Tag
                                            array[rowIndex, 2].Content = "■";
                                            array[rowIndex, 3].Type = TimeAxisCellType.Empty;           // 第 4 列应为底边框线
                                        }
                                        else
                                        {
                                            array[rowIndex, 2].Type = TimeAxisCellType.Tag;           // 第 3 列应为Tag
                                            array[rowIndex, 2].Content = node.Tag;
                                            array[rowIndex, 3].Type = TimeAxisCellType.Line;          // 第 4 列应为底边框线
                                        }
                                    }
                                    array[rowIndex + 1, 2].Type = TimeAxisCellType.Hided;         // 第 3 列下一行单元格应被隐藏


                                }
                                else  // 默认向右
                                {
                                    // 设置对应单元格的状态。
                                    if (string.IsNullOrWhiteSpace(node.Tag))
                                    {
                                        array[rowIndex, 5].Type = TimeAxisCellType.Empty;         // 第 6 列是Line
                                        array[rowIndex, 6].Type = TimeAxisCellType.Empty;         // 第 7 列应为Tag
                                    }
                                    else
                                    {
                                        if (node.Tag == "`--Empty--`")
                                        {
                                            array[rowIndex, 5].Type = TimeAxisCellType.Empty;          // 第 6 列是Line
                                            array[rowIndex, 6].Type = TimeAxisCellType.Empty;          // 第 7 列是Tag
                                            array[rowIndex, 6].Content = "　　";
                                        }
                                        else
                                        {
                                            array[rowIndex, 5].Type = TimeAxisCellType.Line;          // 第 6 列是Line
                                            array[rowIndex, 6].Type = TimeAxisCellType.Tag;           // 第 7 列是Tag
                                            array[rowIndex, 6].Content = node.Tag;
                                        }

                                        array[rowIndex + 1, 6].Type = TimeAxisCellType.Hided;     // 第 7 列下一行单元格应被隐藏
                                    }

                                    if (string.IsNullOrWhiteSpace(node.Comment))
                                    {
                                        array[rowIndex, 7].Type = TimeAxisCellType.Empty;         // 第 8 列Line
                                        array[rowIndex, 8].Type = TimeAxisCellType.EmptyComment;  // 第 9 列Comment
                                    }
                                    else
                                    {
                                        if (node.Tag == "`--Empty--`")
                                        {
                                            array[rowIndex, 7].Type = TimeAxisCellType.Empty;           // 第 8 列Line
                                        }
                                        else
                                        {
                                            array[rowIndex, 7].Type = TimeAxisCellType.Line;           // 第 8 列Line
                                        }

                                        array[rowIndex, 8].Type = TimeAxisCellType.Comment;        // 第 9 列Comment
                                        array[rowIndex, 8].Content = node.Comment;
                                    }
                                    array[rowIndex + 1, 8].Type = TimeAxisCellType.Hided;          // 第 9 列下一行单元格应被隐藏
                                }
                            }

                            for (int cc = 0; cc < 9; cc++) // 逐列判断当前列所有单元格是否均为空或被隐藏
                            {
                                var shouldDisplay = false;
                                for (int cr = 0; cr < array.Length / 9; cr++)
                                {
                                    if (array[cr, cc].Type != TimeAxisCellType.Empty && array[cr, cc].Type != TimeAxisCellType.Hided)
                                    {
                                        shouldDisplay = true;
                                        break;  // 只要有一个应当显示的就结束循环
                                    }
                                }

                                if (shouldDisplay == false)
                                {
                                    for (int cr = 0; cr < array.Length / 9; cr++)
                                    {
                                        array[cr, cc].Type = TimeAxisCellType.Hided; // 全部忽略
                                    }
                                }
                            }

                            for (int ci = 0; ci < array.Length / 9; ci++)
                            {
                                var rowHtml = new StringBuilder();
                                for (int j = 0; j < 9; j++)
                                {
                                    var cell = array[ci, j];
                                    switch (cell.Type)
                                    {
                                        case TimeAxisCellType.Line:
                                            {
                                                rowHtml.Append("<td class='v_time_axis_line'><li class='simple'></li></td>");
                                                break;
                                            }
                                        case TimeAxisCellType.Comment:
                                            {
                                                rowHtml.Append($"<td rowspan='2' class='v_time_axis_comment'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, cell.Content)}</li></td>");
                                                break;
                                            }
                                        case TimeAxisCellType.EmptyComment:
                                            {
                                                rowHtml.Append($"<td rowspan='2' class='v_time_axis_empty'><li class='simple'></li></td>");
                                                break;
                                            }
                                        case TimeAxisCellType.Title:
                                            {
                                                if (ci == 0)
                                                {
                                                    if (string.IsNullOrWhiteSpace(title))
                                                    {
                                                        rowHtml.Append($"<td class='v_time_axis_title' rowspan='{array.Length / 9}'><li class='v_time_axis_title'>时<br>间<br>轴</li></td>");
                                                    }
                                                    else
                                                    {
                                                        rowHtml.Append($"<td class='v_time_axis_title' rowspan='{array.Length / 9}'><li class='v_time_axis_title'>{string.Join("<br>", title.ToCharArray())}</li></td>");
                                                    }
                                                }
                                                break;
                                            }
                                        case TimeAxisCellType.Empty:
                                            {
                                                rowHtml.Append($"<td class='v_time_axis_empty'><li class='simple'></li></td>");
                                                break;
                                            }
                                        case TimeAxisCellType.Tag:
                                            {
                                                rowHtml.Append($"<td rowspan='2' class='v_time_axis_tag'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, cell.Content)}</li></td>");
                                                break;
                                            }
                                            //default:  // 被覆盖的直接忽略
                                    }
                                }

                                var rowText = rowHtml.ToString();
                                if (string.IsNullOrWhiteSpace(rowText) == false)
                                {
                                    htmlStringBuilder.Append("<tr>" + rowText + "</tr>");
                                }
                            }
                            break;
                        }
                    case TimeAxisLayout.SymmetryLayout:
                        {
                            // 纵轴，左右都有，对称布局
                            var ltList = new TimeAxisesList();
                            var rbList = new TimeAxisesList();
                            foreach (var li in list)
                            {
                                switch (li.Direction)
                                {
                                    case TimeAxisDirection.LeftOrTop:
                                        {
                                            ltList.Add(li); break;
                                        }
                                    case TimeAxisDirection.RightOrBottom:
                                        {
                                            rbList.Add(li); break;
                                        }
                                }
                            }

                            var maxCount = Math.Max(ltList.Count, rbList.Count);
                            var rows = maxCount * 3 - 1;

                            var iLtList = ltList.AllCellIndexes;
                            var iRbList = rbList.AllCellIndexes;


                            TimeAxisCell[,] array = new TimeAxisCell[rows, 9];
                            for (int ai = 0; ai < array.Length / 9; ai++)
                            {
                                for (int ac = 0; ac < 9; ac++)
                                {
                                    if (ai >= 1 && ac == 4)
                                    {
                                        array[ai, ac] = new TimeAxisCell()
                                        {
                                            Type = TimeAxisCellType.Hided,   // 中轴
                                        };
                                    }
                                    else
                                    {
                                        array[ai, ac] = new TimeAxisCell()
                                        {
                                            Type = TimeAxisCellType.Empty,
                                        };
                                    }
                                }
                            }

                            for (int li = 0; li < ltList.Count; li++)
                            {
                                var rowIndex = (li * 3 + 1) - 1;

                                array[rowIndex, 4].Type = TimeAxisCellType.Title;             // 第 5 列总为标题

                                var node = ltList[li];
                                if (node.Direction == TimeAxisDirection.LeftOrTop)
                                {
                                    // 设置对应单元格的状态。
                                    if (string.IsNullOrWhiteSpace(node.Comment))
                                    {
                                        array[rowIndex, 0].Type = TimeAxisCellType.EmptyComment;  // 第 1 列是Comment
                                        array[rowIndex, 1].Type = TimeAxisCellType.Empty;         // 第 2 列应为底边框线
                                    }
                                    else
                                    {
                                        array[rowIndex, 0].Type = TimeAxisCellType.Comment;       // 第 1 列是Comment
                                        array[rowIndex, 0].Content = node.Comment;
                                        if (node.Tag == "`--Empty--`")
                                        {
                                            array[rowIndex, 1].Type = TimeAxisCellType.Empty;     // 第 2 列应无底边框线
                                        }
                                        else
                                        {
                                            array[rowIndex, 1].Type = TimeAxisCellType.Line;      // 第 2 列应为底边框线
                                        }
                                    }
                                    array[rowIndex + 1, 0].Type = TimeAxisCellType.Hided;         // 第 1 列下一行单元格应被隐藏


                                    if (string.IsNullOrWhiteSpace(node.Tag))
                                    {
                                        array[rowIndex, 2].Type = TimeAxisCellType.Empty;         // 第 3 列应为Tag
                                        array[rowIndex, 3].Type = TimeAxisCellType.Empty;         // 第 4 列应为底边框线
                                    }
                                    else
                                    {
                                        if (node.Tag == "`--Empty--`")
                                        {
                                            array[rowIndex, 2].Type = TimeAxisCellType.Empty;           // 第 3 列应为Tag
                                            array[rowIndex, 2].Content = "　　";
                                            array[rowIndex, 3].Type = TimeAxisCellType.Empty;          // 第 4 列应为底边框线
                                        }
                                        else
                                        {
                                            array[rowIndex, 2].Type = TimeAxisCellType.Tag;           // 第 3 列应为Tag
                                            array[rowIndex, 2].Content = node.Tag;
                                            array[rowIndex, 3].Type = TimeAxisCellType.Line;          // 第 4 列应为底边框线
                                        }
                                    }
                                    array[rowIndex + 1, 2].Type = TimeAxisCellType.Hided;         // 第 3 列下一行单元格应被隐藏
                                }
                            }

                            for (int li = 0; li < rbList.Count; li++)
                            {
                                var rowIndex = (li * 3 + 1) - 1;

                                array[rowIndex, 4].Type = TimeAxisCellType.Title;             // 第 5 列总为标题  // 不能删除此行！！！

                                var node = rbList[li];
                                if (node.Direction == TimeAxisDirection.RightOrBottom)
                                {
                                    // 设置对应单元格的状态。
                                    if (string.IsNullOrWhiteSpace(node.Tag))
                                    {
                                        array[rowIndex, 5].Type = TimeAxisCellType.Empty;         // 第 6 列是Line
                                        array[rowIndex, 6].Type = TimeAxisCellType.Empty;         // 第 7 列应为Tag
                                    }
                                    else
                                    {
                                        if (node.Tag == "`--Empty--`")
                                        {
                                            array[rowIndex, 5].Type = TimeAxisCellType.Empty;      // 第 6 列是Line
                                            array[rowIndex, 6].Type = TimeAxisCellType.Empty;      // 第 7 列是Tag
                                            array[rowIndex, 6].Content = "　　";
                                        }
                                        else
                                        {
                                            array[rowIndex, 5].Type = TimeAxisCellType.Line;          // 第 6 列是Line
                                            array[rowIndex, 6].Type = TimeAxisCellType.Tag;           // 第 7 列是Tag
                                            array[rowIndex, 6].Content = node.Tag;
                                        }

                                        array[rowIndex + 1, 6].Type = TimeAxisCellType.Hided;     // 第 7 列下一行单元格应被隐藏
                                    }

                                    if (string.IsNullOrWhiteSpace(node.Comment))
                                    {
                                        array[rowIndex, 7].Type = TimeAxisCellType.Empty;         // 第 8 列Line
                                        array[rowIndex, 8].Type = TimeAxisCellType.EmptyComment;  // 第 9 列Comment
                                    }
                                    else
                                    {
                                        if (node.Tag == "`--Empty--`")
                                        {
                                            array[rowIndex, 7].Type = TimeAxisCellType.Empty;      // 第 8 列Line
                                        }
                                        else
                                        {
                                            array[rowIndex, 7].Type = TimeAxisCellType.Line;       // 第 8 列Line
                                        }
                                        array[rowIndex, 8].Type = TimeAxisCellType.Comment;        // 第 9 列Comment
                                        array[rowIndex, 8].Content = node.Comment;
                                    }
                                    array[rowIndex + 1, 8].Type = TimeAxisCellType.Hided;          // 第 9 列下一行单元格应被隐藏
                                }
                            }

                            for (int cc = 0; cc < 9; cc++) // 逐列判断当前列所有单元格是否均为空或被隐藏
                            {
                                var shouldDisplay = false;
                                for (int cr = 0; cr < array.Length / 9; cr++)
                                {
                                    if (array[cr, cc].Type != TimeAxisCellType.Empty && array[cr, cc].Type != TimeAxisCellType.Hided)
                                    {
                                        shouldDisplay = true;
                                        break;  // 只要有一个应当显示的就结束循环
                                    }
                                }

                                if (shouldDisplay == false)
                                {
                                    for (int cr = 0; cr < array.Length / 9; cr++)
                                    {
                                        array[cr, cc].Type = TimeAxisCellType.Hided; // 全部忽略
                                    }
                                }
                            }

                            for (int ci = 0; ci < array.Length / 9; ci++)
                            {
                                var rowHtml = new StringBuilder();
                                for (int j = 0; j < 9; j++)
                                {
                                    var cell = array[ci, j];
                                    switch (cell.Type)
                                    {
                                        case TimeAxisCellType.Line:
                                            {
                                                rowHtml.Append("<td class='v_time_axis_line'><li class='simple'></li></td>");
                                                break;
                                            }
                                        case TimeAxisCellType.Comment:
                                            {
                                                rowHtml.Append($"<td rowspan='2' class='v_time_axis_comment'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, cell.Content)}</li></td>");
                                                break;
                                            }
                                        case TimeAxisCellType.EmptyComment:
                                            {
                                                rowHtml.Append($"<td rowspan='2' class='v_time_axis_empty'><li class='simple'></li></td>");
                                                break;
                                            }
                                        case TimeAxisCellType.Title:
                                            {
                                                if (ci == 0)
                                                {
                                                    if (string.IsNullOrWhiteSpace(title))
                                                    {
                                                        rowHtml.Append($"<td class='v_time_axis_title' rowspan='{array.Length / 9}'><li class='v_time_axis_title'>时<br>间<br>轴</li></td>");
                                                    }
                                                    else
                                                    {
                                                        rowHtml.Append($"<td class='v_time_axis_title' rowspan='{array.Length / 9}'><li class='v_time_axis_title'>{string.Join("<br>", title.ToCharArray())}</li></td>");
                                                    }
                                                }
                                                break;
                                            }
                                        case TimeAxisCellType.Empty:
                                            {
                                                rowHtml.Append($"<td class='v_time_axis_empty'><li class='simple'></li></td>");
                                                break;
                                            }
                                        case TimeAxisCellType.Tag:
                                            {
                                                rowHtml.Append($"<td rowspan='2' class='v_time_axis_tag'><li class='simple'>{CustomMarkdownSupport.FormatLineContent(ref md, cell.Content)}</li></td>");
                                                break;
                                            }
                                            //default:  // 被覆盖的直接忽略
                                    }
                                }

                                var rowText = rowHtml.ToString();
                                if (string.IsNullOrWhiteSpace(rowText) == false)
                                {
                                    htmlStringBuilder.Append("<tr>" + rowText + "</tr>");
                                }
                            }
                            break;
                        }
                }
            }

            htmlStringBuilder.Append("</table>");
            return htmlStringBuilder.ToString();
        }
    }

    public enum TimeAxisCellType
    {
        Comment,
        Line,
        Tag,
        Title,
        Empty,
        EmptyComment,
        Hided,   // 被Tag或Comment单元格覆盖的。
    }

    public class TimeAxisCell
    {
        public string Content { get; set; }

        public TimeAxisCellType Type { get; set; }

    }
}
